home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvi2ps / dvi-to-ps / gf.c < prev    next >
C/C++ Source or Header  |  1990-10-01  |  18KB  |  678 lines

  1. #ifndef USEPXL
  2. /* modified by Peter Damron 1987 University of Washington */
  3. /*---------------------------------------------------------------------*/
  4. #ifndef lint
  5. static char rcsid[] = "$Header: gf.c,v 2.0 88/06/07 15:02:50 peterd Rel2 $";
  6. #endif lint
  7. /*---------------------------------------------------------------------*/
  8.  
  9. #include <stdio.h>
  10. #include "gf.h"
  11.  
  12. /*---------------------------------------------------------------------*/
  13. /* This file contains routines for reading character descriptions from
  14.    GF files (the output of Metafont).  The following functions are defined:
  15.    gf_gettochar() finds the next character, returns its code (reduced modulo
  16.         256 if necessary), and sets global variables gf_min_m, gf_max_m,
  17.         gf_min_n, gf_max_n.  A result of -1 indicates that there are no
  18.         more characters and the postamble has been found.
  19.    gf_readbits() After a character is found, this routine fills array gf_bits[]
  20.         with the character image.  The image is represented in
  21.         Postscript format: the bits are packed into bytes
  22.         (most significant bit first), and the bytes scan the image
  23.         left-to-right, bottom-to-top.
  24.         Set globals gf_num_cols, gf_num_rows, gf_x_offset, gf_y_offset
  25.         (the latter give the offset of the origin from the upper
  26.         bottom corner of the image, up being a positive gf_y_offset).
  27.    gf_readpost() After the postamble is found, this routine reads it and
  28.         sets the remaining global variables declared below.
  29.    gf_seekpost() rapidly finds the postamble by random accessing the file.
  30.    gf_seekchar(c) uses fseek() to find a character with code c (modulo 256),
  31.         returning a nonzero result if successful.  Global variables
  32.         are set as they are by gf_gettochar.  GF files may contain
  33.         many characters with the same code, in which case subsequent
  34.         calls to gf_seekchar(c) with the same c will find the other
  35.         versions.  This routine should only be called after gf_readpost().
  36.    No random access is attempted if gf_seekpost() and gf_seekchar() are not used.
  37. */
  38. /*---------------------------------------------------------------------*/
  39.  
  40. /* use macros versus functions */
  41. #define MACROS 1
  42.  
  43. #ifndef TRUE
  44. #define FALSE    0
  45. #define TRUE    1
  46. #endif TRUE
  47.  
  48. /*---------------------------------------------------------------------*/
  49.  
  50. int gf_min_m;        /* min horz bounding box for character */
  51. int gf_max_m;        /* max horz bounding box for character */
  52. int gf_min_n;        /* min vert bounding box for character */
  53. int gf_max_n;        /* max vert bounding box for character */
  54. int32 gf_charfam;    /* high order bytes of character code */
  55. int gf_cur_char;    /* current character - for error messages */
  56.  
  57. /*---------------------------------------------------------------------*/
  58. /* these variables initialized by gf_readpost() */
  59.  
  60. int gf_font_min_m;    /* min horz overall bounds of this font */
  61. int gf_font_max_m;    /* max horz overall bounds of this font */
  62. int gf_font_min_n;    /* min vert overall bounds of this font */
  63. int gf_font_max_n;    /* max vert overall bounds of this font */
  64. int32 designsize;    /* font size in points scaled by 1<<20 */
  65. int32 gf_checksum;    /* should match TFM file and DVI file */
  66. int32 gf_hppp;        /* horizontal and vertical pixels/point scaled 1<<16 */
  67. int32 gf_vppp;        /* horizontal and vertical pixels/point scaled 1<<16 */
  68.  
  69. int gf_char_wd[MAXCHARS];    /* character width in pixels, rounded if necessary */
  70. int32 gf_tfm_wd[MAXCHARS];    /* width as a fraction of designsize scaled 1<<20 */
  71. char gf_char_exists[MAXCHARS];    /* nonzero indicates presence of a char_loc */
  72. int gf_bc;            /* first nonzero gf_char_exists entries */
  73. int gf_ec;            /* last nonzero gf_char_exists entries */
  74.  
  75. int32 gf_char_pointer[MAXCHARS];    /* used by gf_seekchar() */
  76. int32 gf_backpointer;        /* set by gf_gettochar() for use by gf_seekchar() */
  77.  
  78. /*---------------------------------------------------------------------*/
  79.  
  80. #ifndef MACROS
  81. void gf_beginc();    /* prepare to paint white at (gf_min_m,gf_max_n) */
  82. void gf_paint();    /* paint d pixels and switch colors */
  83. void gf_skip();        /* finish a row and skip d rows */
  84. void gf_endc();        /* finish the last row */
  85. #endif not MACROS
  86.  
  87. /*---------------------------------------------------------------------*/
  88.  
  89. extern void bad_gf();    /* aborts the program if the gf file is invalid */ 
  90. FILE *gf_infile = stdin;    /* change this externally if necessary */
  91. char *gf_filename = 0;        /* name of the currently open font file */
  92.  
  93. /*---------------------------------------------------------------------*/
  94. /* The following macros describe gf file format */
  95.  
  96. #define GF_paint_0    0
  97. #define GF_last_paint    63
  98. #define GF_paint1    64
  99. #define GF_paint2    65
  100. #define GF_paint3    66
  101. #define GF_boc        67
  102. #define GF_boc1        68
  103. #define GF_eoc        69
  104. #define GF_skip0    70
  105. #define GF_skip1    71
  106. #define GF_skip2    72
  107. #define GF_skip3    73
  108. #define GF_new_row_0    74
  109. #define GF_last_new_row    238
  110. #define GF_xxx1        239
  111. #define GF_xxx2        240
  112. #define GF_xxx3        241
  113. #define GF_xxx4        242
  114. #define GF_yyy        243
  115. #define GF_no_op    244
  116. #define GF_char_loc    245
  117. #define GF_char_loc0    246
  118. #define GF_pre        247
  119. #define GF_post        248
  120. #define GF_postpost    249
  121. #define undefined_cases    250: case 251: case 252: case 253: case 254: case 255
  122. #define GF_trailer    223
  123. #define GF_version    131
  124.  
  125. /*---------------------------------------------------------------------*/
  126. /* misc macros for accessing bitmap */
  127.  
  128. #define row_start(n) (&(gf_bits[(n - gf_min_n)*gf_rowbytes]))
  129. #define m_byte(m) ((m - gf_min_m)>>3)    /* byte within a row containing bit m */
  130. #define m_bit(m) (7-(m - gf_min_m)&0x7)    /* bit within byte for a given m */
  131.                     /* bit m on byte boundary? */
  132. #define m_notbyteboundary(m) ((m - gf_min_m)&0x7)
  133.  
  134. /*---------------------------------------------------------------------*/
  135.  
  136. #define BITBUFSIZE 20000
  137.  
  138. unsigned char gf_bits[BITBUFSIZE];
  139. int gf_num_cols;            /* num cols (bits) in bitmap */
  140. int gf_num_rows;            /* num rows (bits) in bitmap */
  141. int gf_num_bytes;            /* num bytes in bitmap */
  142. int gf_x_offset;            /* horz offset of bitmap */
  143. int gf_y_offset;            /* vert offset of bitmap */
  144.  
  145. int gf_rowbytes;            /* num bytes/row in bitmap */
  146. static int gf_m0;        /* current horz bit number (column) */
  147.  
  148. #ifndef MACROS
  149. static int gf_m;        /* current horz bit number (column) */
  150. static int gf_n;        /* current horz bit number (row) */
  151. static int gf_paint_switch;    /* paint white or black */
  152. static unsigned char *gf_row_ptr;    /* pointer to start of current row */
  153. #endif not MACROS
  154.  
  155. /*---------------------------------------------------------------------*/
  156. /* All gf file input goes through the following routines */
  157.  
  158. #define getbyte()    (getc(gf_infile)&0xff)
  159.  
  160. #ifdef NOTDEF
  161. int getbyte()
  162. {
  163.     int b;
  164.     b = getc(gf_infile) & 0xff;
  165.     printf("Getting %d\n",b);
  166.     return b;
  167. }
  168. #endif NOTDEF
  169.  
  170. #define skip1byte()    getc(gf_infile)
  171.  
  172. int get2bytes()
  173. {    register int ans;
  174.     ans = getbyte() << 8;
  175.     ans += getbyte();
  176.     return ans;
  177. }
  178.  
  179. int32 get3bytes()
  180. {    register int32 ans;
  181.     ans = getbyte() << 16;
  182.     ans += getbyte() << 8;
  183.     ans += getbyte();
  184.     return ans;
  185. }
  186.  
  187. int32 get4bytes()
  188. {
  189.     register int32 ans;
  190.     ans = getbyte() << 24;
  191.     ans += getbyte() << 16;
  192.     ans += getbyte() << 8;
  193.     ans += getbyte();
  194.     return ans;
  195. }
  196.  
  197. #ifdef MACROS
  198.  
  199. #define skip_bytes(n)  { \
  200.         while (n-- > 0) skip1byte(); \
  201.     }
  202.  
  203. #else not MACROS
  204.  
  205. void skip_bytes(n)
  206.     int n;
  207. {
  208.     while (n-- > 0) skip1byte();
  209. }
  210. #endif MACROS
  211.  
  212. /*---------------------------------------------------------------------*/
  213. /* In the unlikely event of a character code outside of the range 0..255,
  214.    the high order bytes are placed in the global variable gf_charfam.
  215.    If no boc command is encountered, the result is -1 and the last byte read
  216.    is guaranteed to be the post command.
  217. */
  218.  
  219. int gf_gettochar()
  220. {
  221.     int32 c;        /* the character code to be returned */
  222.     register int x;        /* temporary */
  223.     register int len;    /* temporary */
  224.  
  225.     for(;;) switch(getbyte())
  226.     {
  227.     case GF_yyy: skip1byte();        /* intended to fall through 3 times */
  228.     case GF_paint3: case GF_skip3: skip1byte();
  229.     case GF_paint2: case GF_skip2: skip1byte();
  230.     case GF_paint1: case GF_skip1: skip1byte(); continue;
  231.  
  232.     case GF_boc: c = get4bytes();
  233.         gf_backpointer = get4bytes();
  234.         gf_min_m = get4bytes();
  235.         gf_max_m = get4bytes();
  236.         gf_min_n = get4bytes();
  237.         gf_max_n = get4bytes();
  238.         gf_charfam = c<0 ? -((-c)>>8) : c>>8;
  239.         gf_cur_char = c&0377;
  240.         return c&0377;
  241.  
  242.     case GF_boc1: c = getbyte();
  243.         gf_backpointer =  -1;
  244.         x = getbyte();        /* del_m */
  245.         gf_max_m = getbyte();
  246.         gf_min_m = gf_max_m - x;
  247.         x = getbyte();        /* del_n */
  248.         gf_max_n = getbyte();
  249.         gf_min_n = gf_max_n - x;
  250.         gf_cur_char = c;
  251.         return c;
  252.  
  253.     case GF_pre: if (getbyte() != GF_version) bad_gf(1);
  254.         len = getbyte();
  255.         skip_bytes(len);
  256.         continue;
  257.  
  258.     case GF_xxx1:
  259.         len = getbyte();
  260.         skip_bytes(len);
  261.         continue;
  262.     case GF_xxx2:
  263.         len = get2bytes();
  264.         skip_bytes(len);
  265.         continue;
  266.     case GF_xxx3:
  267.         len = get3bytes();
  268.         skip_bytes(len);
  269.         continue;
  270.     case GF_xxx4:
  271.         len = get4bytes();
  272.         skip_bytes(len);
  273.         continue;
  274.  
  275.     case GF_post: return -1;
  276.  
  277.     case GF_char_loc: case GF_char_loc0: case GF_postpost: case undefined_cases:
  278.         bad_gf(2);
  279.  
  280.     default: /* do nothing */;
  281.     }
  282. }
  283.  
  284. /*---------------------------------------------------------------------*/
  285. /* read the post-amble of a gf format font file */
  286.  
  287. void gf_readpost()
  288. {
  289.     register int i;
  290.     register int b;
  291.     register int c;
  292.  
  293.     get4bytes();    /* ignore back pointer to font-wide xxx commands */
  294.     designsize = get4bytes();
  295.     gf_checksum = get4bytes();
  296.     gf_hppp = get4bytes();
  297.     gf_vppp = get4bytes();
  298.     gf_font_min_m = get4bytes();
  299.     gf_font_max_m = get4bytes();
  300.     gf_font_min_n = get4bytes();
  301.     gf_font_max_n = get4bytes();
  302.  
  303.     for(i = 0; i < MAXCHARS; i++) {
  304.         gf_char_exists[i] = FALSE;
  305.         gf_char_wd[i] = 0;
  306.         gf_tfm_wd[i] = 0;
  307.         gf_char_pointer[i] =  -1;
  308.     }
  309.     gf_bc = MAXCHARS;
  310.     gf_ec = 0;
  311.     for (;;) {
  312.         b = getbyte();
  313.         c = getbyte();
  314.         if (b == GF_char_loc0) {
  315.             gf_char_wd[c] = getbyte();
  316.         } else if (b == GF_char_loc) {
  317.             gf_char_wd[c] = (get4bytes()+0100000)>>16;
  318.             get4bytes();        /* skip dy */
  319.         } else {
  320.             break;
  321.         }
  322.         gf_tfm_wd[c] = get4bytes();
  323.         gf_char_pointer[c] = get4bytes();
  324.         gf_char_exists[c] = TRUE;
  325.         if (gf_bc>c) gf_bc = c;
  326.         if (gf_ec<c) gf_ec = c;
  327.     }
  328.     gf_cur_char = -1;
  329. }
  330.  
  331. /*---------------------------------------------------------------------*/
  332. /* find the post-amble of a gf format font file */
  333.  
  334. void gf_seekpost()
  335. {
  336.     int c;
  337.  
  338.     fseek(gf_infile, -5L, 2);            /* skip four 223's */
  339.     do {
  340.         c = getbyte();
  341.         fseek(gf_infile, -2L, 1);
  342.     } while (c == GF_trailer);
  343.     if (c != GF_version) bad_gf(5);        /* check version number */
  344.     fseek(gf_infile, -3L, 1);        /* back up to the pointer */
  345.     if (fseek(gf_infile, (long) get4bytes(), 0) < 0) bad_gf(6);
  346.     if (getbyte() != GF_post) bad_gf(7);
  347.     gf_cur_char = -1;
  348. }
  349.  
  350. /*---------------------------------------------------------------------*/
  351. /* find a character definition in a gf format font file */
  352.  
  353. int gf_seekchar(c)
  354.     int c;
  355. {
  356.     if (c < 0 || c > MAXCHARS-1 || gf_char_pointer[c] < 0) return FALSE;
  357.     if (fseek(gf_infile, gf_char_pointer[c], 0) < 0) bad_gf(8);
  358.     if (gf_gettochar() != c) bad_gf(9);
  359.     gf_cur_char = c;
  360.     return TRUE;
  361. }
  362.  
  363. /*---------------------------------------------------------------------*/
  364. /* begin a character, initialize data */
  365.  
  366. #ifdef MACROS
  367.  
  368. #define gf_beginc(dummy)  { \
  369.         gf_num_cols = gf_max_m - gf_min_m + 1; \
  370.         gf_num_rows = gf_max_n - gf_min_n + 1; \
  371.         gf_x_offset = -gf_min_m; \
  372.         gf_y_offset = -gf_min_n; \
  373.         gf_rowbytes = (gf_num_cols+7)/8; \
  374.         gf_num_bytes = gf_num_rows*gf_rowbytes; \
  375.         if (gf_num_bytes >= BITBUFSIZE) \
  376.             bad_gf(10); /* really, should allocate a bigger one */ \
  377.         gf_m = gf_m0 = gf_min_m; \
  378.         gf_n = gf_max_n; \
  379.         gf_row_ptr = row_start(gf_max_n); \
  380.         bzero(gf_bits, gf_num_bytes); \
  381.         gf_paint_switch = FALSE; \
  382.     }
  383.  
  384. #else not MACROS
  385.  
  386. void gf_beginc()
  387. {
  388.     gf_num_cols = gf_max_m - gf_min_m + 1;
  389.     gf_num_rows = gf_max_n - gf_min_n + 1;
  390.     gf_x_offset = -gf_min_m;
  391.     gf_y_offset = -gf_min_n;
  392.     gf_rowbytes = (gf_num_cols+7)/8;
  393.     gf_num_bytes = gf_num_rows*gf_rowbytes;
  394.     if (gf_num_bytes >= BITBUFSIZE) {
  395.         bad_gf(10); /* really, should allocate a bigger one */
  396.     }
  397.     gf_m = gf_m0 = gf_min_m;
  398.     gf_n = gf_max_n;
  399.     gf_row_ptr = row_start(gf_max_n);
  400.     bzero(gf_bits, gf_num_bytes);
  401.     gf_paint_switch = FALSE;
  402. }
  403. #endif MACROS
  404.  
  405. /*---------------------------------------------------------------------*/
  406. /* paint a portion of a row of bits into the bitmap */
  407. /* this is a decoding of a run length encoding of a bitmap */
  408. /* d is the number of bits (run length) to encode */
  409. /* gf_paint_switch is a true for one-bits and false for zero bits */
  410. /* this is the old version */
  411.  
  412. #ifdef NOTDEF
  413. void gf_paint(d)
  414.     register int d;
  415. {
  416.     if (d>0) {
  417.         if (gf_paint_switch) {
  418.             while (d-- >0) {
  419.                 gf_row_ptr[m_byte(gf_m)] |= 1<<m_bit(gf_m);
  420.                 gf_m++;
  421.             }
  422.         } else {
  423.             gf_m += d;
  424.         }
  425.     }
  426.     gf_paint_switch ^= 1;
  427. }
  428. #endif NOTDEF
  429.  
  430. /*---------------------------------------------------------------------*/
  431. /* paint a portion of a row of bits into the bitmap */
  432. /* this is a decoding of a run length encoding of a bitmap */
  433. /* d is the number of bits (run length) to encode */
  434. /* gf_paint_switch is a true for one-bits and false for zero bits */
  435. /* row-ptr is a pointer to the beginning of this row */
  436. /* gf_m is the distance (bits) from the beginning of the row (output bitmap) */
  437.  
  438. #ifdef MACROS
  439.  
  440. #define gf_paint(len)  { \
  441.     if (len > 0) { \
  442.         if (gf_paint_switch) { \
  443.         /* paint white (==1) */ \
  444.         /* first fill in the first partial byte */ \
  445.         while ((len > 0) && m_notbyteboundary(gf_m)) { \
  446.             gf_row_ptr[m_byte(gf_m)] |= 1 << m_bit(gf_m); \
  447.             gf_m += 1; \
  448.             len -= 1; \
  449.         } \
  450.         /* now fill in the whole bytes */ \
  451.         while (len > 0) { \
  452.             /* note (gf_m & 0x7 == 0) */ \
  453.             /* this is an even byte boundary */ \
  454.             /* so we know what to put into this byte */ \
  455.             if (len >= 8) { \
  456.             /* this byte is full */ \
  457.             gf_row_ptr[m_byte(gf_m)] = 0xFF; \
  458.             gf_m += 8; \
  459.             len -= 8; \
  460.             } else { \
  461.             /* this byte is partial */ \
  462.             /* len&7 == len div 8 */ \
  463.             gf_row_ptr[m_byte(gf_m)] = (0xFF << (8-len)) & 0xFF; \
  464.             gf_m += len; \
  465.             len = 0; \
  466.             } \
  467.         } \
  468.         gf_paint_switch = FALSE; \
  469.         } else { \
  470.         /* paint black (==0) is easy */ \
  471.         gf_m += len; \
  472.         gf_paint_switch = TRUE; \
  473.         } \
  474.     } else { \
  475.         /* len <= 0 */ \
  476.         if (len < 0) { \
  477.         Warning("internal - unexpected value in gf_paint %d\n",len); \
  478.         } \
  479.         gf_paint_switch = !gf_paint_switch; \
  480.     } \
  481.     }
  482.  
  483. #else not MACROS
  484.  
  485. void gf_paint(len)
  486.     register int len;
  487. {
  488.     /* why was I called? */
  489.     if (len <= 0) {
  490.     if (len < 0) {
  491.         Warning("internal - unexpected value in gf_paint %d\n",len);
  492.     }
  493.     gf_paint_switch = !gf_paint_switch;
  494.     return;
  495.     }
  496.  
  497.     /* paint black (==0) is easy */
  498.     if (!gf_paint_switch) {
  499.     gf_m += len;
  500.     gf_paint_switch = TRUE;
  501.     return;
  502.     }
  503.  
  504.     /* paint white (==1) */
  505.     /* first fill in the first partial byte */
  506.     while ((len > 0) && m_notbyteboundary(gf_m)) {
  507.     gf_row_ptr[m_byte(gf_m)] |= 1 << m_bit(gf_m);
  508.     gf_m += 1;
  509.     len -= 1;
  510.     }
  511.  
  512.     /* now fill in the whole bytes */
  513.     while (len > 0) {
  514.         /* note (gf_m & 0x7 == 0) */
  515.         /* this is an even byte boundary */
  516.         /* so we know what to put into this byte */
  517.     if (len >= 8) {
  518.         /* this byte is full */
  519.         gf_row_ptr[m_byte(gf_m)] = 0xFF;
  520.         gf_m += 8;
  521.         len -= 8;
  522.     } else {
  523.         /* this byte is partial */
  524.         /* len&7 == len div 8 */
  525.         gf_row_ptr[m_byte(gf_m)] = (0xFF << (8-len)) & 0xFF;
  526.         gf_m += len;
  527.         len = 0;
  528.     }
  529.     }
  530.     gf_paint_switch = FALSE;
  531. }
  532. #endif MACROS
  533.  
  534. /*---------------------------------------------------------------------*/
  535. /* skip to the next row of bits */
  536.  
  537. #ifdef MACROS
  538.  
  539. #define gf_skip(d)  { \
  540.         gf_n -= d+1; \
  541.         gf_m = gf_m0; \
  542.         gf_row_ptr = row_start(gf_n); \
  543.         gf_paint_switch = FALSE; \
  544.     }
  545.  
  546. #else not MACROS
  547.  
  548. void gf_skip(d)
  549.     int d;
  550. {
  551.     gf_n -= d+1;
  552.     gf_m = gf_m0;
  553.     gf_row_ptr = row_start(gf_n);
  554.     gf_paint_switch = FALSE;
  555. }
  556. #endif MACROS
  557.  
  558. /*---------------------------------------------------------------------*/
  559. /* end of character */
  560.  
  561. #ifdef MACROS
  562.  
  563. #define gf_endc(dummy)
  564.  
  565. #else not MACROS
  566.  
  567. void gf_endc() { /* do nothing */ }
  568.  
  569. #endif MACROS
  570.  
  571. /*---------------------------------------------------------------------*/
  572. /* gf_readbits reads a raster description from the gf file and uses the external
  573.    routines to actually process the raster information.
  574. */
  575.  
  576. void gf_readbits()
  577. {
  578.     /* register unsigned char byt; */
  579.     register int byt;
  580.     register int len;
  581. #ifdef MACROS
  582.     register unsigned char *gf_row_ptr;    /* start of current row */
  583.     register int gf_m;        /* current horz bit number (column) */
  584.     register int gf_paint_switch;    /* paint white or black */
  585.     register int gf_n;        /* current horz bit number (row) */
  586. #endif MACROS
  587.  
  588.     gf_beginc();
  589.     for (;;) {
  590.         byt = getbyte();
  591.         if (byt <= GF_last_paint) {
  592.             len = byt - GF_paint_0;
  593.             gf_paint(len);
  594.         }
  595.         if (byt < GF_new_row_0) {
  596.             switch(byt) {
  597.             case GF_paint1:
  598.                 len = getbyte();
  599.                 gf_paint(len);
  600.                 continue;
  601.             case GF_paint2:
  602.                 len = get2bytes();
  603.                 gf_paint(len);
  604.                 continue;
  605.             case GF_paint3:
  606.                 len = get3bytes();
  607.                 gf_paint(len);
  608.                 continue;
  609.             case GF_boc:
  610.             case GF_boc1:
  611.                 bad_gf(3);
  612.             case GF_eoc:
  613.                 goto finish;
  614.             case GF_skip0:
  615.                 gf_skip(0);
  616.                 continue;
  617.             case GF_skip1:
  618.                 len = getbyte();
  619.                 gf_skip(len);
  620.                 continue;
  621.             case GF_skip2:
  622.                 len = get2bytes();
  623.                 gf_skip(len);
  624.                 continue;
  625.             case GF_skip3:
  626.                 len = get3bytes();
  627.                 gf_skip(len);
  628.                 continue;
  629.             }
  630.         } else if (byt <= GF_last_new_row) {
  631.             gf_skip(0);
  632.             len = byt - GF_new_row_0;
  633.             gf_paint(len);
  634.         } else {
  635.             switch(byt) {
  636.             case GF_xxx1:
  637.                 len = getbyte();
  638.                 skip_bytes(len);
  639.                 continue;
  640.             case GF_xxx2:
  641.                 len = get2bytes();
  642.                 skip_bytes(len);
  643.                 continue;
  644.             case GF_xxx3:
  645.                 len = get3bytes();
  646.                 skip_bytes(len);
  647.                 continue;
  648.             case GF_xxx4:
  649.                 len = get4bytes();
  650.                 skip_bytes(len);
  651.                 continue;
  652.             case GF_yyy:
  653.                 get4bytes();
  654.                 continue;
  655.             case GF_no_op:
  656.                 continue;
  657.             default:
  658.                 bad_gf(4);
  659.             }
  660.         }
  661.     }
  662. finish:    gf_endc();
  663. }
  664.  
  665. /*---------------------------------------------------------------------*/
  666. /* report errors */
  667.  
  668. void bad_gf(n)
  669.     int n;
  670. {
  671.     Fatal("bad gf font file %s\n  char %d offset %d case %d\n",
  672.         gf_filename,gf_cur_char,ftell(gf_infile),n);
  673. }
  674.  
  675. /*---------------------------------------------------------------------*/
  676. #endif USEPXL
  677.  
  678.